package com.xyh.flowershop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyh.flowershop.cache.RedisCache;
import com.xyh.flowershop.constant.CacheConstant;
import com.xyh.flowershop.constant.CommonConstant;
import com.xyh.flowershop.context.WebContext;
import com.xyh.flowershop.domain.Cart;
import com.xyh.flowershop.domain.Goods;
import com.xyh.flowershop.mapper.CartMapper;
import com.xyh.flowershop.mapper.GoodsMapper;
import com.xyh.flowershop.service.CartService;
import com.xyh.flowershop.vo.req.cart.CartEditReqVo;
import com.xyh.flowershop.vo.req.cart.CartPageReqVo;
import com.xyh.flowershop.vo.req.cart.UpdateCheckedReqVo;
import com.xyh.flowershop.vo.resp.cart.CartPageRespVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author 小约翰可汗
 * @className CartServiceImpl
 * @createTime 2024/5/420:43
 */
@Slf4j
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements CartService {

    private final GoodsMapper goodsMapper;

    private final RedisCache redisCache;

    public CartServiceImpl(GoodsMapper goodsMapper, RedisCache redisCache) {
        this.goodsMapper = goodsMapper;
        this.redisCache = redisCache;
    }

    @Override
    public String addOrEditCart(CartEditReqVo vo) {
//        Boolean flag = false;
        Cart cart = new Cart();
        vo.setUserId(WebContext.get());
        BeanUtils.copyProperties(vo, cart);
        Goods goods = goodsMapper.selectById(vo.getGoodId());
        // 原始总价
        cart.setTotalPrice(goods.getGoodPriceDis().multiply(new BigDecimal(vo.getCount())));
        cart.setUpdateTime(new Date());
        Cart selectCart = baseMapper.selectByCondition(vo);
        if (Objects.isNull(selectCart)) {
            cart.setCreatTime(new Date());
            // 购物车最多添加200件
            LambdaQueryWrapper<Cart> cartWrapper = new LambdaQueryWrapper<>();
            cartWrapper.eq(Cart::getUserId, vo.getUserId());
            cartWrapper.eq(Cart::getDeleted,false);
            if (baseMapper.selectCount(cartWrapper) >= CommonConstant.MAX_CART_COUNT) {
                return "购物车已满";
            }
            baseMapper.insert(cart);
        } else {
            cart.setId(selectCart.getId());
            cart.setCount(selectCart.getCount() + vo.getCount());
            cart.setTotalPrice(goods.getGoodPriceDis().multiply(new BigDecimal(cart.getCount())));
            baseMapper.updateById(cart);
        }
        return cart.getId();
    }

    @Override
    public IPage<CartPageRespVo> findPageCarts(CartPageReqVo vo) {
        vo.setUserId(WebContext.get());
        if (vo.getPageIndex() <= 0 || vo.getPageIndex() == null) vo.setPageIndex(1L);
        if (vo.getPageSize() <= 0 || vo.getPageSize() == null) vo.setPageIndex(10L);
        IPage<CartPageRespVo> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        page = baseMapper.selectPageCarts(page, vo);
        return page;
    }

    @Override
    public Boolean deleteCarts(List<String> ids) {

        return baseMapper.removeCarts(ids) > 0;
    }

    @Override
    public CartPageRespVo findCart(String id) {
        CartPageReqVo vo = new CartPageReqVo();
        vo.setId(id);
        IPage<CartPageRespVo> pageCarts = this.findPageCarts(vo);
        return pageCarts.getRecords().size() > 0 ? pageCarts.getRecords().get(0) : new CartPageRespVo();
    }

    @Override
    public void addCacheCart(List<String> ids) {
        String userId = WebContext.get();
        // 先清空该用户的购物车缓存
        redisCache.deleteObject(CacheConstant.CART_ORDER_PREFIX + userId);
        // 再添加缓存
        redisCache.setCacheObject(CacheConstant.CART_ORDER_PREFIX + userId, ids, 15, TimeUnit.MINUTES);
    }

    @Override
    public List<CartPageRespVo> findCacheCarts() {
        Object cacheObject = redisCache.getCacheObject(CacheConstant.CART_ORDER_PREFIX + WebContext.get());
        List<String> ids = null;
        List<CartPageRespVo> carts = null;
        if (Objects.nonNull(cacheObject) && cacheObject instanceof List) {
            ids = (List<String>) cacheObject;
            log.info("getCacheCart: ids={}", ids);
            if(ids.size() > 0){
                carts = baseMapper.selectCartsByIds(ids, WebContext.get());
            }
        }
        return carts;
    }

    @Override
    public void updateChecked(UpdateCheckedReqVo vo) {
        vo.setUserId(WebContext.get());
        if(Objects.nonNull(vo.getIsAll()) && vo.getIsAll()){
            baseMapper.updateCheckedAll(vo.getUserId(),vo.getIsAllChecked());
        }else{

            baseMapper.updateChecked(vo.getId(),vo.getIsCheck());
        }
    }
}
